package model

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"log"
	"next-vue-backend/utils/errmsg"
	"time"
)

type Comment struct {
	ArticleId int      `json:"article_id"`
	Article   Article  `gorm:"foreignKey:ArticleId;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
	UserId    int      `json:"user_id"`
	CommentId int      `gorm:"primary_key;auto_increment" json:"comment_id"`
	User      User     `gorm:"foreignKey:UserId;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
	ParentId  int      `gorm:"index;default:0"`
	Parent    *Comment `gorm:"foreignKey:ParentId;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
	Content   string   `gorm:"type:varchar(500);not null" json:"content"`
	Status    int8     `gorm:"type:tinyint;default:2" json:"status"`
	CreatedAt time.Time
	UpdatedAt time.Time
}

// CommentTree 评论树
type CommentTree struct {
	CommentId int                    `json:"commentId"`
	Content   string                 `json:"content"`
	User      map[string]interface{} `json:"user"`
	CreatedAt string                 `json:"createdAt"`
	Children  []*CommentTree         `json:"children"`
}

// AddCommentForm 新增评论表单
type AddCommentForm struct {
	UserId    int    `form:"user_id" json:"user_id" binding:"required"`
	ArticleId int    `form:"article_id" json:"article_id" binding:"required"`
	ParentId  int    `form:"parentId" json:"parentId" binding:"gte=0"`
	Content   string `form:"content" json:"content" binding:"required,max=1024"`
}

// AddComment 新增评论
func AddComment(data *Comment) int {
	data.CreatedAt = time.Now()
	err = db.Create(&data).Error
	if err != nil {
		return errmsg.ERROR
	}
	return errmsg.SSUCCESS
}

// DeleteComment 删除评论
func DeleteComment(id uint) int {
	var comment Comment
	err = db.Where("comment_id = ?", id).Delete(&comment).Error
	if err != nil {
		return errmsg.ERROR
	}
	return errmsg.SSUCCESS
}

// GetSingleComment 获取单条评论
func GetSingleComment(id int) (Comment, int) {
	var comment Comment
	var user User
	err = db.Preload("User").Where("comment_id = ?", id).First(&comment).Error
	db.Model(&comment).Association("User").Find(&user)
	if err != nil {
		return comment, errmsg.ERROR
	}
	return comment, errmsg.SSUCCESS
}

// GetCommentList (后台)获取评论列表
func GetCommentList(pageSize int, pageNum int) ([]Comment, int64, int) {
	var commentList []Comment
	var total int64
	db.Find(&commentList).Count(&total)
	err = db.Model(&commentList).
		Limit(pageSize).
		Offset((pageNum - 1) * pageSize).
		Order("Created_At DESC").
		Select("comment.comment_id, article.title,user_id,article_id, user.username, comment.content, comment.status,comment.created_at").
		Joins("LEFT JOIN article ON comment.article_id = article.article_id").
		Joins("LEFT JOIN user ON comment.user_id = user.user_id").
		Scan(&commentList).Error
	if err != nil {
		return commentList, 0, errmsg.ERROR
	}
	return commentList, total, errmsg.SSUCCESS
}

// CommentTreeVO 评论树
type CommentTreeVO struct {
	CommentId int    `json:"commentId"`
	Content   string `json:"content"`
	Username  string `json:"username"`
	Avatar    string `json:"avatar"`
	CreatedAt string `json:"createdAt"`
	ParentId  int    `json:"parentId"`
}

func QueryCommentList(articleId int) ([]*CommentTreeVO, int) {
	commentList := make([]*CommentTreeVO, 0)
	/*var user User
	err = db.Preload("User").Where("article_id = ?", articleId).Find(&commentList).Error
	db.Model(&commentList).Association("User").Find(&user)*/
	sql := "select t.comment_id,\n" +
		"       t.content,\n" +
		"       t.parent_id as parent_id,\n " +
		"       DATE_FORMAT(t.created_at,'%Y-%m-%d %H:%i:%s') as created_at,\n " +
		"      u.username,\n" +
		"       u.avatar\n" +
		"from comment t\n" +
		"         left join user u on u.user_id = t.user_id\n" +
		"where t.article_id = ? "
	data, code := queryList(sql, articleId)
	if code == errmsg.ERROR {
		fmt.Println(code)
	} else {
		fmt.Println(data)
	}
	rows, err := db.Raw(sql, articleId).Rows()
	if err != nil {
		log.Println(err.Error())
		return commentList, errmsg.ERROR
	}
	for rows.Next() {
		commentTreeVO := &CommentTreeVO{}
		db.ScanRows(rows, &commentTreeVO)
		commentList = append(commentList, commentTreeVO)
	}
	return commentList, errmsg.SSUCCESS
}

// GetCommentCount 获取评论数量
func GetCommentCount(id int) int64 {
	var comment Comment
	var total int64
	err = db.Find(&comment).Where("article_id = ?", id).Where("status = ?", 1).Count(&total).Error
	if err != nil {
		return 0
	}
	return total
}

// GetCommentListFront 打开文章获取评论列表
func GetCommentListFront(id int, pageSize int, pageNum int) ([]Comment, int64, int) {
	var commentList []Comment
	var total int64
	db.Find(&commentList).Where("article_id = ?", id).Count(&total)
	err = db.Model(&commentList).Limit(pageSize).Offset((pageNum-1)*pageSize).
		Order("Created_At DESC").
		Select("comment.comment_id, article.title, user_id, article_id, user.username, user.avatar, comment.content, comment.status,comment.created_at").
		Joins("LEFT JOIN article ON comment.article_id = article.article_id").
		Joins("LEFT JOIN user ON comment.user_id = user.user_id").
		Where("article_id = ?", id).
		Where("status = ?", 1).
		Scan(&commentList).
		Error
	if err != nil {
		return commentList, 0, errmsg.ERROR
	}
	return commentList, total, errmsg.SSUCCESS
}

// GetCommentListByArticleId 按文章获取评论列表
func GetCommentListByArticleId(articleId int) []CommentTree {
	var commentTrees []CommentTree
	var comments []Comment
	db.Where("article_id = ? AND parent_id IS NULL", articleId).Order("comment_id desc").Find(&comments)
	for _, comment := range comments {
		var user User
		commentId := comment.UserId
		userId := comment.UserId
		db.Where("user_id = ?", userId).First(&user)
		commentTree := CommentTree{
			CommentId: commentId,
			Content:   comment.Content,
			User:      gin.H{"user_id": userId, "username": user.Username, "avatar": user.Avatar},
			CreatedAt: comment.CreatedAt.Format("2006-01-02 15:04"),
			Children:  []*CommentTree{},
		}
		GetArticleCommentChild(commentId, &commentTree)
		commentTrees = append(commentTrees, commentTree)
	}
	return commentTrees
}

// GetArticleCommentChild 获取文章评论的子集
func GetArticleCommentChild(id int, commentTree *CommentTree) {
	var comments []Comment
	db.Where("parent_id = ?", id).Find(&comments)

	for i, _ := range comments {
		var user User
		commentId := comments[i].CommentId
		userId := comments[i].UserId
		db.Where("user_id = ?", userId).First(&user)
		child := CommentTree{
			CommentId: commentId,
			Content:   comments[i].Content,
			User:      gin.H{"user_id": user.UserId, "username": user.Username, "avatar": user.Avatar},
			CreatedAt: comments[i].CreatedAt.Format("2006-01-02 15:04"),
			Children:  []*CommentTree{},
		}
		commentTree.Children = append(commentTree.Children, &child)
		GetArticleCommentChild(commentId, &child)
	}
}

// CheckedComment (后台)通过评论
func CheckedComment(id int, data *Comment) int {
	var comment Comment
	var res Comment
	var article Article
	var maps = make(map[string]interface{})
	maps["status"] = data.Status
	err = db.Model(&comment).Where("comment_id = ?", id).Updates(maps).First(&res).Error
	db.Model(&article).Where("comment_id = ?", res.ArticleId).UpdateColumn("comment_count", gorm.Expr("comment_count + ?", 1))
	if err != nil {
		return errmsg.ERROR
	}
	return errmsg.SSUCCESS
}

// CloseComment (后台)关闭评论
func CloseComment(id int, data *Comment) int {
	var comment Comment
	var res Comment
	var article Article
	var maps = make(map[string]interface{})
	maps["status"] = data.Status

	err = db.Model(&comment).Where("comment_id = ?", id).Updates(maps).First(&res).Error
	db.Model(&article).Where("comment_id = ?", res.ArticleId).UpdateColumn("comment_count", gorm.Expr("comment_count = ?", 1))
	if err != nil {
		return errmsg.ERROR
	}
	return errmsg.SSUCCESS
}
